package com.tqz.jvm.cicuitbreaker;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 *
 * @author tianqingzhao
 * @since 2022/10/20 20:19
 */
public class Counter {
    
    /**
     * closed 状态进入open 状态的错误个数阈值
     */
    private final int failreCount;
    
    /**
     * failureCount 统计时间窗口
     */
    private final long failureTimeInterval;
    
    /**
     * 当前错误次数
     */
    private final AtomicInteger currentCount;
    
    /**
     * 上一次调用失败的时间戳
     */
    private long lastTime;
    
    /**
     * half_open 状态下成功次数
     */
    private final AtomicInteger halfOpenSuccessCount;
    
    public Counter(int failreCount, long failureTimeInterval) {
        this.failreCount = failreCount;
        this.failureTimeInterval = failureTimeInterval;
        this.currentCount = new AtomicInteger(0);
        this.halfOpenSuccessCount = new AtomicInteger(0);
        this.lastTime = System.currentTimeMillis();
    }
    
    public synchronized  int incrFailureCount() {
        long current = System.currentTimeMillis();
        // 超过时间窗口，当前失败次数重置为0
        if (current - lastTime > failureTimeInterval) {
            lastTime = current;
            currentCount.set(0);
        }
        
        return currentCount.getAndIncrement();
    }
    
    public int incrSuccessHalfOpenCount() {
        return this.halfOpenSuccessCount.incrementAndGet();
    }
    
    public boolean failureThresholdReached() {
        return getCurCount() >= failreCount;
    }
    
    public int getCurCount() {
        return currentCount.get();
    }
    
    public synchronized void reset() {
        halfOpenSuccessCount.set(0);
        currentCount.set(0);
    }
}
